/*
 * ServiceLocator.java
 *
 * Created on 18 de julio de 2005, 12:34 PM
 *
 * To change this template, choose Tools | Options and locate the template under
 * the Source Creation and Management node. Right-click the template and choose
 * Open. You can then make changes to the template in the Source Editor.
 */

package com.src.computec.radar.base.servicelocator;

import java.util.*;
import javax.naming.*;
import javax.sql.*;
import com.src.computec.radar.base.servicelocator.exception.ServiceLocatorException;
import javax.ejb.EJBHome;
import javax.jms.QueueConnectionFactory;
import javax.rmi.PortableRemoteObject;

/**
 *
 * @author Santiago
 */

public class ServiceLocator {
    
    private static ServiceLocator instance = null;
    private Context context;
    private Hashtable dataSources;
    private Hashtable homes;
    private Hashtable queueConnectionFactories;

    /** Crea una instancia de ServiceLocator */
    private ServiceLocator() {
        dataSources = new Hashtable();
        homes = new Hashtable();
        context = this.getInitialContext();
        queueConnectionFactories = new Hashtable();
    }

    /** Obtiene el objeto singleton de la clase ServiceLocator*/
    public static ServiceLocator getInstance() {
        if (instance == null) {
            instance = new ServiceLocator();
        }
        return instance;
    }

    /** 
     * Obtiene un datasourse
     * @param dataSourceName    el nombre del datasource
     * @remote                  indica si el dataource es remoto
     * @return                  el DataSource solicitado
     */
    public DataSource getDataSource(String dataSourceName, boolean remote) throws ServiceLocatorException {
        DataSource dsReturn = null;
        if (!dataSources.containsKey(dataSourceName)){
            try {
                if (remote){
                    dsReturn = (DataSource) context.lookup(dataSourceName);
                }
                dataSources.put(dataSourceName, dsReturn);
            }
            catch (NamingException ex) {
                throw new ServiceLocatorException("ServiceLocator:getDataSource: Error localizando el componente " + dataSourceName, ex);
            }
        }
        else {
            dsReturn = (DataSource)dataSources.get(dataSourceName);
        }
        return dsReturn;
    }

    /** Obtiene el Home de un ejb
     * @param ejbName   el nombre del ejb
     * @param clazz     el objeto Class del home del EJB
     * @return          EJBHome del EJB
     */

    public EJBHome getHome(String ejbName, Class clazz) throws ServiceLocatorException {
        EJBHome ejbHomeReturn = null;
        if (homes.containsKey(ejbName)) {
            ejbHomeReturn = (EJBHome)homes.get(ejbName);
        }
        else {
            try {
                Object temp = context.lookup(ejbName);
                ejbHomeReturn = (EJBHome) PortableRemoteObject.narrow(temp, clazz);
                homes.put(ejbName, ejbHomeReturn);
            }
            catch(NamingException e) {
                throw new ServiceLocatorException("ServiceLocator:getHome: Error localizando el componente " + ejbName, e);
            }
        }
        return ejbHomeReturn;
    }

    public QueueConnectionFactory getQueueConnectionFactory(String jndiName)throws ServiceLocatorException {
        QueueConnectionFactory retorno = null;
        if (!queueConnectionFactories.containsKey(jndiName)) {
            try {
                retorno = (QueueConnectionFactory)context.lookup(jndiName);
                queueConnectionFactories.put(jndiName, retorno);
            }
            catch (NamingException ex) {
                throw new ServiceLocatorException("ServiceLocator:getQueueConnectionFactory: Error localizando el componente " + jndiName, ex);
            }
        }
        else {
            retorno = (QueueConnectionFactory)queueConnectionFactories.get(jndiName);
        }
        return retorno;
    }

    public Queue getQueue(String jndiName)throws ServiceLocatorException {
        Queue retorno = null;
        try {
            retorno = (Queue)context.lookup(jndiName);
        }
        catch (NamingException ex) {
            throw new ServiceLocatorException("ServiceLocator:getQueue: Error localizando el componente " + jndiName, ex);
        }
        return retorno;
    }

    private Context getInitialContext() {
        Context retorno = null;
        
        try {
            retorno = new InitialContext();
        }
        catch (Exception e) {
            System.out.println("ERROR: Ocurrio un error grave creando el contexto: " + e.getMessage());
            e.printStackTrace();
        }
        return retorno;
    }
}